﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SSharp.Core.DataTypes;
using SSharp.Core.Builtins.Functions.Util;
using SSharp.Core.Evaluator;
using System.Numerics;

namespace SSharp.Core.Builtins.Functions {
	public static class PrimitiveTypeChecks {
		public static readonly PrimitiveProcedure IsInteger = new PrimitiveProcedure("integer?",
			args => {
				if (args.Length != 1) {
					throw new ApplicationError("integer? expected one argument, given " + args.Length);
				}
				return args[0] is BigInteger;
			});

		public static readonly PrimitiveProcedure IsDecimal = new PrimitiveProcedure("decimal?",
			args => {
				if (args.Length != 1) {
					throw new ApplicationError("decimal? expected one argument, given " + args.Length);
				}
				return args[0] is decimal;
			});

		public static readonly PrimitiveProcedure IsNumber = new PrimitiveProcedure("number?",
			args => {
				if (args.Length != 1) {
					throw new ApplicationError("number? expected one argument, given " + args.Length);
				}
				return args[0] is BigInteger || args[0] is decimal;
			});

		public static readonly PrimitiveProcedure IsString = new PrimitiveProcedure("string?",
			args => {
				if (args.Length != 1) {
					throw new ApplicationError("string? expected one argument, given " + args.Length);
				}
				return args[0] is string;
			});

		public static readonly PrimitiveProcedure IsSymbol = new PrimitiveProcedure("symbol?",
			args => {
				if (args.Length != 1) {
					throw new ApplicationError("symbol? expected one argument, given " + args.Length);
				}
				return args[0] is Symbol;
			});

		public static readonly PrimitiveProcedure IsEmpty = new PrimitiveProcedure("empty?",
			args => {
				if (args.Length != 1) {
					throw new ApplicationError("empty? expected one argument, given " + args.Length);
				}
				return args[0] is List.EmptyList;
			});

		public static readonly PrimitiveProcedure IsPair = new PrimitiveProcedure("pair?",
			args => {
				if (args.Length != 1) {
					throw new ApplicationError("pair? expected one argument, given " + args.Length);
				}
				return args[0] is Cons;
			});

		public static readonly PrimitiveProcedure IsNull = new PrimitiveProcedure("null?",
			args => {
				if (args.Length != 1) {
					throw new ApplicationError("null? expected one argument, given " + args.Length);
				}
				return ReferenceEquals(args[0], null);
			});
	}
}
